package gui;

import application.CouleurTank;
import application.Mouvement;
import application.PowerUp;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Point2D;

public class Tank extends ElementDuJeu {

    Monde monde;
    Canon canon;
    Mouvement mouvement = new Mouvement();
    Image tankBase;
    private CouleurTank couleurTank;
    private Area aireGenerale, aireObstacles;
    private AffineTransform atHitbox;
    double VITESSE_TANK = 2.0;
    final double RAD_ROTATION = 0.02;
    final int longueurCanon = 76;
    double xSouris, ySouris, angleViseCanon, angleViseTank, angleActuelTank, i, j, xActuelTank, yActuelTank;
    boolean rotationTank, mouvementEnclenche, vivant, reverse, peutRam;
    int xCibleMouvement, yCibleMouvement, tankX, tankY, xCibleReverse, yCibleReverse;
    int fuel, projectilesRestants, hP;
    int maxHP = 10;
    int ramPower = 1;
    int dmg = 1;
    int fuelMax = 750;
    int nombreProjectiles = 1;
    PowerUp pU;

    public Tank(int posX, int posY, CouleurTank couleur, Monde mundo) {
        setLocation(posX, posY);
        setSize(162, 162);

        couleurTank = couleur;
        monde = mundo;
        canon = new Canon(0, 0, couleurTank, this, monde);
        monde.add(canon);

        tankX = this.getWidth() / 2;
        tankY = this.getHeight() / 2;
        xCibleMouvement = this.getX();
        yCibleMouvement = this.getY();
        xActuelTank = this.getX();
        yActuelTank = this.getY();
        mouvementEnclenche = false;
        vivant = true;
        reverse = false;
        fuel = fuelMax;
        hP = maxHP;
        projectilesRestants = nombreProjectiles;
        peutRam = true;



        angleActuelTank = 180.0;

        do {
            if (couleurTank == CouleurTank.VERT) {
                tankBase = Toolkit.getDefaultToolkit().getImage(ClassLoader.getSystemResource("images/Tank_Base_Vert.png"));
            } else if (couleurTank == CouleurTank.BLEU) {
                tankBase = Toolkit.getDefaultToolkit().getImage(ClassLoader.getSystemResource("images/Tank_Base_Bleu.png"));
            } else if (couleurTank == CouleurTank.JAUNE) {
                tankBase = Toolkit.getDefaultToolkit().getImage(ClassLoader.getSystemResource("images/Tank_Base_Jaune.png"));
            } else if (couleurTank == CouleurTank.ROUGE) {
                tankBase = Toolkit.getDefaultToolkit().getImage(ClassLoader.getSystemResource("images/Tank_Base_Rouge.png"));
            }
        } while (tankBase.getHeight(monde) == -1 || tankBase.getWidth(monde) == -1);

        aireGenerale = new Area(new Rectangle((int) (this.getX() + tankX - tankBase.getWidth(monde) / 2 + 4), (int) (this.getY() + tankY - tankBase.getHeight(monde) / 2 + 8), tankBase.getHeight(monde), tankBase.getWidth(monde) + 1));
        aireObstacles = new Area(new Rectangle((int) (this.getX() + tankX - tankBase.getWidth(monde) / 2 + 4), (int) (this.getY() + tankY - tankBase.getHeight(monde) / 2 + 8), tankBase.getHeight(monde)/4, tankBase.getWidth(monde)+1));
        atHitbox = new AffineTransform();
    }

    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2dTankBase = (Graphics2D) g;
        if (vivant) {
            g2dTankBase.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2dTankBase.rotate(Math.toRadians(angleActuelTank + 90), tankX, tankY);
            g2dTankBase.drawImage(tankBase, canon.getCanonX() - 22, canon.getCanonY() - 18, this);
        }

    }

    void bouger(MouseEvent e) {
        xCibleMouvement = e.getX();
        yCibleMouvement = e.getY();
        angleViseTank = mouvement.calculerAngle(xCibleMouvement - this.getX() - tankX, yCibleMouvement - this.getY() - tankY);
        rotationTank = true;
        mouvementEnclenche = true;


    }

    void bougerCibleCanon(MouseEvent e) {
        xSouris = e.getX() - (this.getX() + canon.getCanonX());
        ySouris = e.getY() - this.getY() - canon.getCanonY();
    }

    void progressionDeMouvement() {
        //Orientation du tank
        if (fuel >= 0 && rotationTank) {
            if (Math.abs(angleActuelTank - angleViseTank) < 2) {
                rotationTank = false;
            } else {
                angleActuelTank = mouvement.angleDeRotation(angleViseTank, angleActuelTank, RAD_ROTATION);

                //Definit le sens de la rotation                                
                atHitbox.setToRotation(mouvement.getSensRotation() * RAD_ROTATION, this.getX() + tankX, this.getY() + this.tankY);
                aireGenerale.transform(atHitbox);
                aireObstacles.transform(atHitbox);
                repaint();
                fuel -= 1;
            }
        }





        if (fuel >= 0 && mouvementEnclenche && !rotationTank && Math.abs(Math.abs(xCibleMouvement) - Math.abs(this.getX() + tankX)) > 2 && Math.abs(Math.abs(yCibleMouvement) - Math.abs(this.getY() + tankY - 20)) > 2) {
            i = mouvement.getIJ(this.getX() + tankX, this.getY() + tankY - 20, xCibleMouvement, yCibleMouvement)[0];
            j = mouvement.getIJ(this.getX() + tankX, this.getY() + tankY - 20, xCibleMouvement, yCibleMouvement)[1];
            xActuelTank += i * VITESSE_TANK;
            yActuelTank += j * VITESSE_TANK;
            this.setLocation((int) (xActuelTank), (int) (yActuelTank));
            atHitbox = new AffineTransform();
            atHitbox.translate(this.getX() - (int) (xActuelTank - i * VITESSE_TANK), this.getY() - (int) (yActuelTank - j * VITESSE_TANK));
            aireGenerale.transform(atHitbox);
            aireObstacles.transform(atHitbox);
            fuel -= 2;

        }


        //Rotation Canon        
        canon.progressionDeMouvement(angleViseCanon, xSouris, ySouris, RAD_ROTATION);
    }

    public int getBoutDuCanonCanonX() {
        return canon.getBoutDuCanonX();
    }

    public int getBoutDuCanonCanonY() {
        return canon.getBoutDuCanonY();
    }

    public int getCanonX() {
        return canon.getCanonX();
    }

    public int getCanonY() {
        return canon.getCanonY();
    }

    public double getAngleActuelCanon() {
        return canon.getAngleActuelCanon();
    }

    public Area getAire() {
        return aireGenerale;
    }
    
    public Area getAireObstacle() {
        return aireObstacles;
    }

    public int getHP() {
        return hP;
    }

    public void resetTour() {
        fuel = fuelMax;
        projectilesRestants = nombreProjectiles;
        xCibleMouvement = this.getX() + tankX;
        yCibleMouvement = this.getY() + tankY + 20;
        angleViseTank = angleActuelTank;
        peutRam = true;
    }

    public void setPowerUP(PowerUp pU) {
        this.pU=pU;
        switch (pU) {
            case PLUS_DE_VIE: {
                this.maxHP = maxHP + (int) (maxHP);
                hP = maxHP;

            }
            break;
            case PLUS_DE_DMG:
                this.dmg = dmg * 2;
                break;
            case PLUS_DE_FUEL: {
                this.fuelMax = fuelMax + (int) (fuelMax * 0.5);
                fuel = fuelMax;
            }
            break;
            case PLUS_DE_RAM:
                this.ramPower = ramPower + 2;

                break;
            case PLUS_DE_PROJECTILES: {
                this.nombreProjectiles = nombreProjectiles * 2;
                projectilesRestants = nombreProjectiles;
            }
            break;
        }
    }

    public void reduceHP(int dmgInflicted) {
        hP -= dmgInflicted;
    }

    public void setVivant(boolean vivant) {
        this.vivant = vivant;
    }

    public void reverseStart() {
        reverse = true;
        xCibleReverse = (int) ((this.getX() + tankX) + (-i * 50));
        yCibleReverse = (int) ((this.getY() + tankY) + (-j * 50));

        i = -i;
        j = -j;
    }

    public void reverse() {
        if (Math.abs(Math.abs(xCibleReverse) - Math.abs(this.getX() + tankX)) > 2 && Math.abs(Math.abs(yCibleReverse) - Math.abs(this.getY() + tankY - 20)) > 2) {

            xActuelTank += i * VITESSE_TANK / 4;
            yActuelTank += j * VITESSE_TANK / 4;
            this.setLocation((int) (xActuelTank), (int) (yActuelTank));
            atHitbox = new AffineTransform();
            atHitbox.translate(this.getX() - (int) (xActuelTank - i * VITESSE_TANK / 4), this.getY() - (int) (yActuelTank - j * VITESSE_TANK / 4));
            aireGenerale.transform(atHitbox);
            aireObstacles.transform(atHitbox);
            fuel -= 1;
        } else {
            reverse = false;
            xCibleMouvement = (int) xActuelTank + tankX;
            yCibleMouvement = (int) yActuelTank + tankY;
        }
        //Rotation Canon

        canon.progressionDeMouvement(angleViseCanon, xSouris, ySouris, RAD_ROTATION);
    }
}
